package qj.ac.deploy;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.util.Collections;
import java.util.Map;

import qj.tool.build.BuildUtil;
import qj.util.DateUtil;
import qj.util.DigestUtil;
import qj.util.EncryptUtil4;
import qj.util.FileUtil;
import qj.util.HttpUtil;
import qj.util.HttpUtil.HttpMessage;
import qj.util.IOUtil;
import qj.util.LanguageUtil;
import qj.util.NetUtil;
import qj.util.SystemUtil;

public class DeployUtil {

//	public static void main(String[] args) {
//		System.out.println(new File("/Users/quanle/Documents/Workon/qj-svn/commercial-apps/store_man/web/data/db").getAbsoluteFile());
//		System.out.println(new File("data/db").getAbsoluteFile());
//	}
	public static void deploy(Class<?> clazz, String address, Map config) {
		deploy(clazz, address, null, config);
	}
	public static void deploy(Class<?> clazz, String address, String key, Map config) {
		String appName = clazz.getSimpleName();
		
		deploy(appName, clazz, address, key, config);
	}
	
	public static void deploy(String appName, Class<?> clazz, String address) {
		deploy(appName, clazz, address, null, Collections.emptyMap());
	}

	public static void deploy(String appName, Class<?> clazz, String address, String key,
			Map config) {
		byte[] fileContent = deploy(clazz, config);
		
		deploy(appName, address, key, fileContent);
	}
	public static void deploy(String appName, String address, String key,
			byte[] fileContent) {
//		System.out.println("Connecting to " + address);
		Socket sk = NetUtil.socket(address);
		
		try {
			long start = System.currentTimeMillis();
			System.out.print("Sending to host " + address + "... ");
			HttpMessage reqO = HttpUtil.HttpMessage.post("/?action=deploy&appId=" + appName + (key==null ? "" : "&key=" + DigestUtil.digest(key + System.currentTimeMillis()/5/DateUtil.MINUTE_LENGTH)));
//			reqO.setHeader("key", address); // TODO
			reqO.send(sk.getOutputStream(), fileContent);
			IOUtil.close(sk);
			System.out.println("done. " + LanguageUtil.translateMillis((System.currentTimeMillis() - start)));
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
	public static byte[] deploy(Class<?> clazz, Map config) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		
		System.out.print("Building zip file... ");
		BuildUtil.writeZipFile(SystemUtil.classPaths1(), clazz.getName(), out, config);
		byte[] fileContent = out.toByteArray();
		System.out.println("done. " + LanguageUtil.translateFileSize(fileContent.length, 2));
		return fileContent;
	}

	public static void stop(Class<?> clazz, String address) {
		String appName = clazz.getSimpleName();

		stop(appName, address);
	}

	public static void stop(String appName, String address) {
		stop(appName, address, null);
	}
	
	public static void stop(String appName, String address, String key) {
		Socket sk = NetUtil.socket(address);
		
		try {
			HttpMessage reqO = HttpUtil.HttpMessage.post("/?action=stop&appId=" + appName + (key==null ? "" : "&key=" + DigestUtil.digest(key + System.currentTimeMillis()/5/DateUtil.MINUTE_LENGTH)));
//			reqO.setHeader("key", address) TODO
			reqO.send(sk.getOutputStream());
			IOUtil.close(sk);
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	public static void restart(Class<?> clazz, String address) {
		String appName = clazz.getSimpleName();
		restart(appName, address);
	}
	
	public static void restart(String appName, String address) {
		restart(appName, address, null);
	}

	public static void restart(String appName, String address, String key) {
		Socket sk = NetUtil.socket(address);

		try {
			HttpMessage reqO = HttpUtil.HttpMessage.post("/?action=restart&appId=" + appName + (key==null ? "" : "&key=" + DigestUtil.digest(key + System.currentTimeMillis()/5/DateUtil.MINUTE_LENGTH)));
//			reqO.setHeader("key", address) TODO
			reqO.send(sk.getOutputStream());
			IOUtil.close(sk);
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
}
